
package com.trydofor.id.a9id;

import javax.annotation.concurrent.Immutable;

import com.trydofor.id.core.A9DU;
import com.trydofor.id.core.A9Maker;
import com.trydofor.id.core.ApiExceptions;
import com.trydofor.id.core.Range;

/**
 * Abstract A9id Maker.
 * 
 * @author Shi Rongjiu (www.trydofor.com)
 * @since 0.9
 */
@Immutable
public abstract class A9idAbstractMaker implements A9Maker<A9ID>, A9DU {
    
    /**
     * the default second epoch.
     * 2011-02-14 00:00:00 GMT+0000
     */
    public static final long SECOND_BASEEPOCH = 1297641600L;
    
    /**
     * the default serial start with
     */
    public static final int  SERIAL_STARTWITH = 1;
    
    /**
     * the default serial increment
     */
    public static final int  SERIAL_INCREMENT = 1;
    
    /**
     * the worker
     */
    protected final int      worker;
    
    /**
     * the second epoch
     */
    protected final long     epoch;
    
    /**
     * hold and check worker & epoch
     * 
     * @param worker the worker
     * @param epoch the second epoch
     * @throws IllegalArgumentException if out of range.
     */
    protected A9idAbstractMaker(int worker, long epoch) {
        Range rwk = A9ID.getRangeOfWorker();
        ApiExceptions.checkRangeNotContains(rwk, worker);
        
        long second = currentSecond() - epoch;
        Range rts = A9ID.getRangeOfSecond();
        ApiExceptions.checkRangeNotContains(rts, second);
        
        this.worker = worker;
        this.epoch = epoch;
    }
    
    /**
     * {@inheritDoc}
     */
    public int getWorker() {
        return worker;
    }
    
    /**
     * get current second
     * 
     * @return current second
     */
    protected long currentSecond() {
        return System.currentTimeMillis() / 1000;
    }
}
